package com.gxd.redis.config;

import com.gxd.commons.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.*;

/**
 * @Author:gxd
 * @Description:
 * @Date: 11:56 2018/4/13
 * @Modified By:
 */
@Configuration
public class RedisConfig {
    private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
    @Autowired(required = false)
    @Qualifier("gxdRedisProperties")
    private RedisProperties redisProperties;

    @Bean(name="jedisCluster")
    public JedisCluster getJedisCluster() {
        //获取服务器数组(这里要相信自己的输入，所以没有考虑空指针问题)
        String nodeStr = redisProperties.getNodes();
        if(StringUtils.isEmpty(nodeStr)){
            return null;
        }
        String [] nodeArr = nodeStr.split(",");
        Set<HostAndPort> nodes = new HashSet<>();

        for (String node : nodeArr) {
            String[] ipPortPair = node.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
        }
        return new JedisCluster(nodes, redisProperties.getConnectionTimeout(), redisProperties.getSoTimeout(), redisProperties.getMaxAttempts(), getRedisConfig());
    }

    @Bean(name="jedisPoolConfig")
    public JedisPoolConfig getRedisConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
        jedisPoolConfig.setMinIdle(redisProperties.getMinIdle());
        jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
        //超时时间
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
        jedisPoolConfig.setMinEvictableIdleTimeMillis(redisProperties.getMinEvictableIdleTimeMillis());
        jedisPoolConfig.setNumTestsPerEvictionRun(redisProperties.getNumTestsPerEvictionRun());       jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
        jedisPoolConfig.setTestOnBorrow(redisProperties.getTestOnBorrow());
        jedisPoolConfig.setTestOnReturn(redisProperties.getTestOnReturn());
        return jedisPoolConfig;
    }

    @Bean(name="redisConnectionFactory")
    public JedisConnectionFactory redisConnectionFactory() {
        if(redisProperties.getNodes()!= null && redisProperties.getNodes().contains(",")){
            RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(Arrays.asList(redisProperties.getNodes().split(",")));
            redisClusterConfiguration.setMaxRedirects(redisProperties.getMaxRedirects());
            logger.debug("load redis cluster success {} ", redisProperties.getNodes().toString());
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            // 最大空闲连接数
            jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
            // 最小空闲连接数
            jedisPoolConfig.setMinIdle(redisProperties.getMinIdle());
            // 最大连接数
            jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
            // 获取连接时的最大等待毫秒数
            jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
            jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
            jedisPoolConfig.setMinEvictableIdleTimeMillis(redisProperties.getMinEvictableIdleTimeMillis());
            jedisPoolConfig.setNumTestsPerEvictionRun(redisProperties.getNumTestsPerEvictionRun());       jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
            jedisPoolConfig.setTestOnBorrow(redisProperties.getTestOnBorrow());
            jedisPoolConfig.setTestOnReturn(redisProperties.getTestOnReturn());
            return new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
        }else{
            JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
            redisConnectionFactory.setHostName(redisProperties.getHost());
            redisConnectionFactory.setPort(redisProperties.getPort());
            redisConnectionFactory.setTimeout(redisProperties.getTimeout());
            if(redisProperties.getPassword() != null){
                redisConnectionFactory.setPassword(redisProperties.getPassword());
            }
            redisConnectionFactory.setDatabase(redisProperties.getDatabase());
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            // 最大空闲连接数
            jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
            // 最小空闲连接数
            jedisPoolConfig.setMinIdle(redisProperties.getMinIdle());
            // 最大连接数
            jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
            // 获取连接时的最大等待毫秒数
            jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
            jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
            jedisPoolConfig.setMinEvictableIdleTimeMillis(redisProperties.getMinEvictableIdleTimeMillis());
            jedisPoolConfig.setNumTestsPerEvictionRun(redisProperties.getNumTestsPerEvictionRun());       jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());

            jedisPoolConfig.setTestOnBorrow(redisProperties.getTestOnBorrow());
            jedisPoolConfig.setTestOnReturn(redisProperties.getTestOnReturn());
            redisConnectionFactory.setPoolConfig(jedisPoolConfig);
            // 初始化连接pool
            redisConnectionFactory.afterPropertiesSet();
            logger.debug("load redis single success {} ", redisProperties.getHost().toString());
            return redisConnectionFactory;
        }
    }

    @Bean(name="sessionRedisTemplate")
    public RedisTemplate<Object, Object> sessionRedisTemplate(@Qualifier("redisConnectionFactory") JedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        logger.debug("sessionRedisTemplate 初始化成功......");
        return template;
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(@Qualifier("redisConnectionFactory") JedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        logger.debug("redisTemplate 初始化成功......");
        return template;
    }
}
